package com.example.studentalarm.calendar;

import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

import com.example.studentalarm.utils.LogUtil;

public class CalendarView extends View {

    private static final String TAG = "CalendarView";

    /**
     * 列
     */
    private static final int TOTAL_COL = 7;
    /**
     * 行
     */
    private static final int TOTAL_ROW = 6;

    private Paint BlueBgPaint, HuiseBgPaint, mCirclePaint, linePaint;
    private Paint mTextPaint, mCutTextPaint;
    private int mViewWidth;//控件宽度
    private int mViewHight;//控件高度
    private float mCellSpace, mCellwide;//方格的宽和高
    private Row rows[] = new Row[TOTAL_ROW];//行数组
    private static RepayPlanInfo mShowDate;// 自定义的单元格信息 包括year month day
    private CallBack mCallBack;// 回调
    private int touchSlop;
    private float radius;//提醒圆的半径
    private Cell mClickCell = null;//点击的单元格
    private float mDownX;
    private float mDownY;
    private boolean callBackCellSpace = false;
    private RepayPlanInfo selectDate;
    String[] str = {"日", "一", "二", "三", "四", "五", "六"};

    public interface CallBack {

        void clickDate(RepayPlanInfo date);// 回调点击的日期

        void onMesureCellHeight(float mCellSpace, float mCellwide);/// 回调cell的高度确定slidingDrawer高度

        void changeDate(RepayPlanInfo date);// 回调滑动viewPager改变的日期
    }

    public CalendarView(Context context, RepayPlanInfo mShowDate, CallBack mCallBack) {
        super(context);
        this.mShowDate = mShowDate;
        this.mCallBack = mCallBack;
        this.selectDate = new RepayPlanInfo(mShowDate.year, mShowDate.month, mShowDate.day, 0);
        init(context);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画顶部的星期
        drawWeek(canvas);
        //画日期单元格
        for (int i = 0; i < TOTAL_ROW; i++) {
            if (rows[i] != null)
                rows[i].drawCells(canvas);
        }
    }

    private void drawWeek(Canvas canvas) {
        for (int i = 0; i < TOTAL_COL; i++) {
            if (i == 0) {
                mTextPaint.setColor(Color.parseColor("#b1b1b1"));
            } else {
                mTextPaint.setColor(Color.parseColor("#80000000"));
            }
            canvas.drawText(str[i], (float) ((i + 0.5) * mCellSpace - mTextPaint.measureText(str[i]) / 2),
                    (float) (0.5 * mCellwide + mTextPaint.measureText(str[i]) / 2), mTextPaint);
        }
        canvas.drawLine(0, mCellwide, mViewWidth, mCellwide, linePaint);
    }

    //初始化画笔
    private void init(Context context) {
        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mCutTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        linePaint.setTextSize(0.5f);
        linePaint.setColor(0x20000000);

        BlueBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        BlueBgPaint.setStyle(Paint.Style.FILL);
        BlueBgPaint.setColor(Color.parseColor("#3693fd"));

        HuiseBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        HuiseBgPaint.setStyle(Paint.Style.FILL);
        HuiseBgPaint.setColor(Color.parseColor("#e9e9e9"));

        mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mCirclePaint.setStyle(Paint.Style.FILL);
        mCirclePaint.setColor(Color.parseColor("#fa4548"));

        touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        initDate();

    }

    private void initDate() {
        if (mShowDate == null) {
            mShowDate = new RepayPlanInfo();
        }
        //填充日期的数据
        fillDate();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mViewWidth = w;
        mViewHight = h;
        mCellSpace = mViewWidth / TOTAL_COL;
        radius = mCellSpace / 4;//红色圆圈的半径，这里根据单元格宽度确定
        //要在第一行顶部留下画圆的高度，所以这里减去半径
        mCellwide = (mViewHight - radius) / 7;
        if (!callBackCellSpace) {
            mCallBack.onMesureCellHeight(mCellSpace, mCellwide);
            callBackCellSpace = true;
        }
        mTextPaint.setTextSize(mCellSpace / 3);
        mCutTextPaint.setTextSize(mCellSpace / 6);
        mCutTextPaint.setColor(Color.parseColor("#fffffe"));

    }

    /*
     *
     * 触摸事件为了确定点击的位置日期
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mDownX = event.getX();
                mDownY = event.getY();
                break;
            case MotionEvent.ACTION_UP:
                float disX = event.getX() - mDownX;
                float disY = event.getY() - mDownY;
                if (Math.abs(disX) < touchSlop && Math.abs(disY) < touchSlop && event.getY() > mCellwide) {
                    int col = (int) (mDownX / mCellSpace);
                    int row = (int) ((mDownY - mCellwide) / mCellwide);
                    measureClickCell(col, row);
                }
                break;
        }
        return true;
    }

    /**
     * 计算绘制点击的单元格
     *
     * @param col
     * @param row
     */
    private void updateClickCell(int col, int row) {
        if (col >= TOTAL_COL || row >= TOTAL_ROW)
            return;
        if (mClickCell != null) {
            rows[mClickCell.j].cells[mClickCell.i] = mClickCell;
        }
        if (rows[row] != null) {
            mClickCell = new Cell(rows[row].cells[col].date, rows[row].cells[col].state, rows[row].cells[col].i,
                    rows[row].cells[col].j);
            rows[row].cells[col].state = State.CLICK_DAY;
            RepayPlanInfo date = rows[row].cells[col].date;
            date.week = col;
            invalidate();
        }
    }

    /**
     * 计算绘制点击的单元格
     *
     * @param col
     * @param row
     */
    private void measureClickCell(int col, int row) {
        if (col >= TOTAL_COL || row >= TOTAL_ROW)
            return;
        if (mClickCell != null) {
            rows[mClickCell.j].cells[mClickCell.i] = mClickCell;
        }
        if (rows[row] != null) {
            mClickCell = new Cell(rows[row].cells[col].date, rows[row].cells[col].state, rows[row].cells[col].i,
                    rows[row].cells[col].j);
            rows[row].cells[col].state = State.CLICK_DAY;
            RepayPlanInfo date = rows[row].cells[col].date;
            date.week = col;
            mCallBack.clickDate(date);
            invalidate();
        }
    }

    // 组
    class Row {
        public int j;

        Row(int j) {
            this.j = j;
        }

        public Cell[] cells = new Cell[TOTAL_COL];

        public void drawCells(Canvas canvas) {
            for (int i = 0; i < cells.length; i++) {
                if (cells[i] != null)
                    cells[i].drawSelf(canvas);
            }

        }
    }

    // 单元格
    class Cell {
        public RepayPlanInfo date;
        public State state;
        /**
         * i = 行 j = 列
         */
        public int i;
        public int j;

        public Cell(RepayPlanInfo date, State state, int i, int j) {
            super();
            this.date = date;
            this.state = state;
            this.i = i;
            this.j = j;
        }

        // 绘制一个单元格 如果颜色需要自定义可以修改
        public void drawSelf(Canvas canvas) {
            switch (state) {
                case CURRENT_MONTH_DAY:
                    mTextPaint.setColor(Color.parseColor("#80000000"));
                    break;
                case NEXT_MONTH_DAY:
                case PAST_MONTH_DAY:
                    mTextPaint.setColor(Color.parseColor("#b1b1b1"));
                    break;
                case TODAY:
                    mTextPaint.setColor(Color.parseColor("#F24949"));
                    break;
                case CLICK_DAY:
                    mTextPaint.setColor(Color.parseColor("#fffffe"));
                    canvas.drawRect((float) (mCellSpace * i), (float) (mCellwide * (j + 1) + radius / 2),
                            (float) (mCellSpace * (i + 1)), (float) (mCellwide * (j + 2) + radius / 2), BlueBgPaint);
                    break;
                case REMIND_DAY:
                    mTextPaint.setColor(Color.parseColor("#80000000"));
                    canvas.drawRect((float) (mCellSpace * i), (float) (mCellwide * (j + 1) + radius / 2),
                            (float) (mCellSpace * (i + 1)), (float) (mCellwide * (j + 2) + radius / 2), HuiseBgPaint);

                    break;
            }
            // 绘制日期文字
            String content = date.day + "";
            canvas.drawText(content, (float) ((i + 0.5) * mCellSpace - mTextPaint.measureText(content) / 2),
                    (float) ((j + 1.5) * mCellwide + mTextPaint.measureText(content, 0, 1) / 2 + radius / 2),
                    mTextPaint);

            // 绘制右上角提示
            String count = date.count + "";
            if (!"0".equals(count)) {
                canvas.drawCircle((float) (mCellSpace * (i + 1) - radius / 2),
                        (float) ((j + 1) * mCellwide + radius / 2), radius / 2, mCirclePaint);
                canvas.drawText(count, (float) (mCellSpace * (i + 1) - radius / 2 - mCutTextPaint.measureText("3") / 2),
                        (float) ((j + 1) * mCellwide + radius / 2 + mCutTextPaint.measureText("3") / 2), mCutTextPaint);
            }
        }
    }

    /**
     * 单元格状态： 当前月日期，过去的月的日期，下个月的日期，今天，点击的日期，提醒日期
     */
    enum State {
        CURRENT_MONTH_DAY, PAST_MONTH_DAY, NEXT_MONTH_DAY, TODAY, CLICK_DAY, REMIND_DAY;
    }

    /**
     * 填充日期的数据
     */
    private void fillDate() {
        fillMonthDate();
    }

    private void fillMonthDate() {

        LogUtil.d(" mshowdate = " + mShowDate.toString() + "  selectDate = " + selectDate.toString());
        // 上个月的天数
        int lastMonthDays = DateUtil.getMonthDays(mShowDate.year, mShowDate.month - 1);
        // 当前月的天数
        int currentMonthDays = DateUtil.getMonthDays(mShowDate.year, mShowDate.month);
        //当月1号是星期几
        int firstDayWeek = DateUtil.getWeekDayFromDate(mShowDate.year, mShowDate.month);
        int day = 0;
        boolean isCurrentMonth = false;
        if (mShowDate.year == selectDate.getYear() && mShowDate.month == selectDate.getMonth()) {
            isCurrentMonth = true;
        }
        for (int j = 0; j < TOTAL_ROW; j++) {
            rows[j] = new Row(j);
            for (int i = 0; i < TOTAL_COL; i++) {
                int postion = i + j * TOTAL_COL;// 单元格位置
                // 这个月的
                if (postion >= firstDayWeek && postion < firstDayWeek + currentMonthDays) {
                    day++;
                    if (isCurrentMonth && selectDate.getDay() == day) {
                        RepayPlanInfo date = RepayPlanInfo.modifiDayForObject(mShowDate, day, 0);
                        mClickCell = new Cell(date, State.TODAY, i, j);
                        date.week = i;
                        rows[j].cells[i] = new Cell(date, State.CLICK_DAY, i, j);
                        continue;
                    }
                    rows[j].cells[i] = new Cell(RepayPlanInfo.modifiDayForObject(mShowDate, day, 0),
                            State.CURRENT_MONTH_DAY, i, j);
                } else if (postion < firstDayWeek) {
                    // 上个月
                    rows[j].cells[i] = new Cell(new RepayPlanInfo(mShowDate.year, mShowDate.month - 1,
                            lastMonthDays - (firstDayWeek - postion - 1), 0), State.PAST_MONTH_DAY, i, j);
                } else if (postion >= firstDayWeek + currentMonthDays) {
                    // 下个月
                    rows[j].cells[i] = new Cell((new RepayPlanInfo(mShowDate.year, mShowDate.month + 1,
                            postion - firstDayWeek - currentMonthDays + 1, 0)), State.NEXT_MONTH_DAY, i, j);
                }
            }
        }
    }

    /**
     * 绘制提醒单元格
     */
    public void updateMonthDate(List<RepayPlanInfo> dateInfos) {
        RepayPlanInfo dateInfo;
        for (int k = 0; k < dateInfos.size(); k++) {
            dateInfo = dateInfos.get(k);
            //当前显示view为提醒月时绘制提醒日期
            if (mShowDate.year == dateInfo.getYear() && mShowDate.month == dateInfo.getMonth()) {
                int[] cut = getSubscript(dateInfo.getDay());
                rows[cut[0]].cells[cut[1]].state = State.REMIND_DAY;
                rows[cut[0]].cells[cut[1]].date = dateInfo;
                if (mClickCell != null && mClickCell.date.getDay() == dateInfo.getDay()) {
                    mClickCell = rows[cut[0]].cells[cut[1]];
                    updateClickCell(cut[1], cut[0]);
                }
            }
        }
        invalidate();
    }

    /**
     * 根据日期获得单元格下标
     *
     * @param i
     * @return
     */
    private int[] getSubscript(int i) {
        int firstDayWeek = DateUtil.getWeekDayFromDate(mShowDate.year, mShowDate.month);
        i = i + firstDayWeek - 1;
        int a = i / 7;
        int b = i % 7;
        int[] cut = {a, b};
        return cut;
    }

    //更新日期，用于月份切换时
    public void update() {
        mClickCell = null;
        mCallBack.changeDate(mShowDate);
        fillDate();
        invalidate();
    }

    //返回当前时间
    public void backToday() {
        initDate();
        invalidate();
    }

    // 点击选择切换月份
    public void clickSelect(int year, int month) {
        mShowDate.month = month;
        mShowDate.year = year;
        update();
    }

    // 向右滑动
    public void rightSilde() {
        if (mShowDate.month == 12) {
            mShowDate.month = 1;
            mShowDate.year += 1;
        } else {
            mShowDate.month += 1;
        }
        update();
    }

    // 向左滑动
    public void leftSilde() {
        if (mShowDate.month == 1) {
            mShowDate.month = 12;
            mShowDate.year -= 1;
        } else {
            mShowDate.month -= 1;
        }
        update();
    }
}